﻿/*
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * See product pages for more information.
 * http://closesudoku.codeplex.com
 * Copyright (C), 2010, hrondra
 */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Fluid.Controls;
using Close;
using Close.Controls;
using Close.Classes;
using System.Runtime.InteropServices;
using Close.Properties;
using Close.controls;

namespace Close
{

    public partial class MainForm : Form
    {
        private LevelsPanel _levelMenu;

        [DllImport("coredll.dll", EntryPoint = ("GetSystemMetrics"))]
        public static extern int GetSystemMetrics(int nIndex);
        private const int SM_CXSCREEN = 0;
        private const int SM_CYSCREEN = 1;


        private int _currentGameLevel;

        public MainForm()
        {
            InitializeComponent();
            if (ThemeClass.Settings.AutoSizeHeight || ThemeClass.Settings.AutoSizeWidth)
            {

                try
                {
                    int menuHeight = this.Menu != null ? SystemInformation.MenuHeight : 0;

                    ThemeClass.Settings.DisplayHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height - menuHeight;
                    ThemeClass.Settings.DisplayWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;

                    ThemeClass.Settings.DisplayHeight = (int)(ThemeClass.Settings.DisplayHeight / DetectResolutionFactorY());
                    ThemeClass.Settings.DisplayWidth = (int)(ThemeClass.Settings.DisplayWidth / DetectResolutionFactorX());
                }
                catch (Exception ex)
                {
                    MyLog.Write(MyLog.LogType.Warning, "Display resolution", "", ex);
                }
            }

            MyLog.Write(MyLog.LogType.Message, "Application started", string.Format("{0}:{1}x{2}", ThemeClass.Settings.AutoSizeHeight, ThemeClass.Settings.DisplayWidth, ThemeClass.Settings.DisplayHeight));

            Host.Bounds = new Rectangle(0, 0, ThemeClass.Settings.DisplayHeight, ThemeClass.Settings.DisplayWidth); //Host.ClientBounds;

            if (ThemeClass.Settings.PowerSaving)
                PowerSaving.DisableDeviceSleep();
//#if DEBUG
//            StartGame(3);
//            return;
//#endif

            OpenLevelPanel();

        }

        /// <summary>
        /// User selected difficulty - show games.
        /// </summary>
        private void levelMenu_ItemClick(object sender, ListBoxItemEventArgs e)
        {
            int level = ((LevelsPanel)sender).SelectedIndex + 1;
            ((LevelsPanel)sender).Close();
            ((LevelsPanel)sender).Dispose();
            OpenGamePanel(level);
        }

        /// <summary>
        /// Detect display resolution
        /// </summary>
        /// <returns>display coeficient</returns>
        private float DetectResolutionFactorY()
        {
            return this.CurrentAutoScaleDimensions.Height / 96.0F;
        }
        /// <summary>
        /// Detect display resolution
        /// </summary>
        /// <returns>display coeficient</returns>
        private float DetectResolutionFactorX()
        {
            return this.CurrentAutoScaleDimensions.Width / 96.0F;
        }
        /// <summary>
        /// Open menu to select difficulty level.
        /// </summary>
        private void OpenLevelPanel()
        {
            _levelMenu = new LevelsPanel();
            LevelsPanel levelMenu = new LevelsPanel();
            SetMenu(Screens.SelectLevel);
            _levelMenu.ShowMaximized();
            _levelMenu.ItemClick += new EventHandler<ListBoxItemEventArgs>(levelMenu_ItemClick);
        }

        /// <summary>
        /// Show list of games.
        /// </summary>
        /// <param name="level">Selected difficulty</param>
        private void OpenGamePanel(int level)
        {
            _currentGameLevel = level;
            GamesPanel gameMenu = new GamesPanel(level);
            SetMenu(Screens.Other);
            gameMenu.BindData(); //HACK: init is called before constructor - do it better
            gameMenu.ShowMaximized();
            gameMenu.ButtonBackClicked += new EventHandler<EventArgs>(levelMenu_ButtonBackClicked);
            gameMenu.ItemClick += new EventHandler<ListBoxItemEventArgs>(gameMenu_ItemClick);
        }

        /// <summary>
        /// Clicked in menu - start the selected game.
        /// </summary>
        void gameMenu_ItemClick(object sender, ListBoxItemEventArgs e)
        {
            //TODO: own object
            String selectedCaption = ((GamesPanel)sender).SelectedText;
            ushort gid = ushort.Parse(selectedCaption.Split(' ')[0]);

            ((GamesPanel)sender).Close();
            ((GamesPanel)sender).Dispose();
            StartGame(gid);
        }

        /// <summary>
        /// Back from games menu to difficulty.
        /// </summary>
        void levelMenu_ButtonBackClicked(object sender, EventArgs e)
        {
            ((GamesPanel)sender).Close();
            ((GamesPanel)sender).Dispose();
            OpenLevelPanel();
        }


        /// <summary>
        /// Start/continue in selected game.
        /// </summary>
        /// <param name="gid">Game id.</param>
        void StartGame(ushort gid)
        {
            MainGui mg = new MainGui(gid);
            mg.BackColor = Color.Black;
            mg.ExitClick += new EventHandler(mg_ExitClick);
            mg.ShowMaximized(ShowTransition.None);
        }

        /// <summary>
        /// Exit from the played game.
        /// </summary>
        /// <param name="sender">main game panel</param>
        /// <param name="e"></param>
        void mg_ExitClick(object sender, EventArgs e)
        {
            ((MainGui)sender).Close();
            ((MainGui)sender).Dispose();
            OpenGamePanel(_currentGameLevel);
        }

        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode == System.Windows.Forms.Keys.Up))
            {
                // Up
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Down))
            {
                // Down
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Left))
            {
                // Left
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Right))
            {
                // Right
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Enter))
            {
                // Enter
            }

        }
        bool _closingConfirmed = false;

        private void MainForm_Closing(object sender, CancelEventArgs e)
        {
            if (_closingConfirmed)
            {
                e.Cancel = false;
            }
            else
            {
                MessageDialog msgReallyQuit = new MessageDialog();
                msgReallyQuit.Message = Resources.QuitQuestion;
                msgReallyQuit.OkText = Resources.RestartGameYes;
                msgReallyQuit.CancelText = Resources.RestartGameNo;
                msgReallyQuit.Result += new EventHandler<Fluid.Classes.DialogEventArgs>(msgReallyQuit_Result);
                msgReallyQuit.ShowModal(ShowTransition.FromBottom);

                e.Cancel = true;
            }
        }

        /// <summary>
        /// Quit the game - yes/no clicked
        /// </summary>
        void msgReallyQuit_Result(object sender, Fluid.Classes.DialogEventArgs e)
        {
            switch (e.Result)
            {
                case System.Windows.Forms.DialogResult.OK:
                    _closingConfirmed = true;
                    this.Close();
                    break;
            }
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            //TODO: rotation of the display
        }

        private void menuItem2_Click(object sender, EventArgs e)
        {
            SetMenu(MainForm.Screens.Other);
            EditLevel editLevel = new EditLevel();
            editLevel.NewGame = false;
            editLevel.LevelId = _levelMenu.SelectedItem.Id;
            editLevel.LevelName = _levelMenu.SelectedItem.Title;
            editLevel.EditLevelClosed += RefreshLevelList;
            editLevel.ShowMaximized();
        }

        /// <summary>
        /// Refresh level panel.
        /// </summary>
        /// <param name="ReLoadLevels">Load Levels</param>
        private void RefreshLevelList(bool ReLoadLevels)
        {
            SetMenu(MainForm.Screens.SelectLevel);
            if(ReLoadLevels)
            {
                Data.GameDatabase data = Data.GameDatabase.GamesData;
                _levelMenu.Reload();
            }

        }

        public enum Screens
        {
            SelectLevel,
            Other
        }

        /// <summary>
        /// Set menu label (and disable/enable).
        /// </summary>
        /// <param name="forScreen">screen</param>
        public void SetMenu(Screens forScreen)
        {
            switch (forScreen)
            {
                case Screens.SelectLevel:
                    menuItem2.Enabled = true;
                    menuItem2.Text = Resources.LevelEditMenu; 
                    break;
                case Screens.Other:
                    menuItem2.Enabled = false;
                    menuItem2.Text = String.Empty;
                    break;
                default:
                    break;
            }

        }
    }
}